package co.liyao.service;

import co.liyao.dto.RoleDto;
import co.liyao.dto.UserOnlineVo;
import co.liyao.mapper.RoleMapper;
import co.liyao.mapper.UserMapper;
import co.liyao.mapper.UserRoleMapper;
import co.liyao.model.Role;
import co.liyao.model.User;
import co.liyao.model.UserRole;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.DefaultSessionKey;
import org.apache.shiro.session.mgt.SessionManager;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.support.DefaultSubjectContext;
import org.crazycake.shiro.RedisCacheManager;
import org.crazycake.shiro.RedisSessionDAO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;

/**
 * @Auther: liyao
 * @Date: 2019/1/27 21:29
 * @Description:
 */
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;




    @Autowired
    private RedisCacheManager redisCacheManager;

    @Autowired
    private SessionManager sessionManager;

    @Autowired
    private RedisSessionDAO redisSessionDAO;

    public List<User> findAll(){
        return userMapper.selectAll();
    }

    public User selectByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    public List<User> selectUsers(User user) {
        return userMapper.selectUsers(user);
    }

    public List<RoleDto> findSelectedRoleByUserId(int id){

        List<Role> user = roleMapper.selectAll();

        List<Integer> integers = userMapper.selectRoleIdByUserId(id);

        List<RoleDto> dto = new LinkedList<>();  // 里面有已经选中的集合

        for (Role ro:user) {
            if(integers.contains(ro.getId())){
                RoleDto role = new RoleDto();
                role.setSelected(true);
                role.setRole(ro);
                dto.add(role);
            }else{
                RoleDto norole = new RoleDto();
                norole.setRole(ro);
                norole.setSelected(false);
                dto.add(norole);
            }
        }






//        for (Role ro:user) {
//            if (integers.size() == 0){
//                RoleDto dto1 = new RoleDto();
//                dto1.setRole(ro);
//                dto1.setSelected(false);
//                dto.add(dto1);
//            } else{
//                for (Integer in: integers) {
//                    RoleDto dto1 = new RoleDto();
//                    if(ro.getId().equals(in)){
//                        dto1.setSelected(true);
//                        dto1.setRole(ro);
//                    }else{
//                        dto1.setSelected(false);
//                        dto1.setRole(ro);
//                    }
//                    dto.add(dto1);
//                }
//            }
//        }
        return dto;
    }

    @Transactional
    public void updateRoleIdbyUserId(Integer userId,Long[] roleId){
        userRoleMapper.delRoleByUserId(userId);
        for (Long lo:roleId) {
            UserRole ur = new UserRole();
            ur.setUserId(String.valueOf(userId));
            ur.setRoleId(String.valueOf(lo));
            userRoleMapper.insert(ur);
        }
    }

    public List<UserOnlineVo> onlineVoList(UserOnlineVo userVo){
        Collection<Session> activeSessions = redisSessionDAO.getActiveSessions();

        Iterator<Session> iterator = activeSessions.iterator();

        List<UserOnlineVo> online = new LinkedList<>();

        while(iterator.hasNext()){
            Session session = iterator.next();
            Object kickout =  session.getAttribute("kickout");
            if(kickout!=null && (boolean)kickout){
                continue;
            }
            PrincipalCollection principalCollection = (PrincipalCollection) session.getAttribute(DefaultSubjectContext.PRINCIPALS_SESSION_KEY);
            if(principalCollection == null){
                continue;
            }
            Object primaryPrincipal =  principalCollection.getPrimaryPrincipal();
            User user = new User();
            BeanUtils.copyProperties(primaryPrincipal,user);
            UserOnlineVo userBo = new UserOnlineVo();
            //最后一次和系统交互的时间
            userBo.setLastAccess(session.getLastAccessTime());
            //主机的ip地址
            userBo.setHost(user.getLoginIpAddress());
            //session ID
            userBo.setSessionId(session.getId().toString());
            //最后登录时间
            userBo.setLastLoginTime(user.getLastLoginTime());
            //回话到期 ttl(ms)
            userBo.setTimeout(session.getTimeout());
            //session创建时间
            userBo.setStartTime(session.getStartTimestamp());
            //是否踢出
            userBo.setSessionStatus(false);
            /*用户名*/
            userBo.setUsername(user.getUsername());

            if(StringUtils.isNotBlank(userVo.getUsername())){
                if(userBo.getUsername().contains(userVo.getUsername()) ){
                    online.add(userBo);
                }
            }else{
                online.add(userBo);
            }

        }
        return online;
    }
    public void kickout(String sessionId, String username) {
        Session session = sessionManager.getSession(new DefaultSessionKey(sessionId));
//        Session session = redisSessionDAO.readSession(sessionId);
        session.setAttribute("kickout",true);
    }


    public int updateByUserId(User user)  {
        return userMapper.updateByUserId(user);
    }


    public User selectByUserId(String userId) {
        return userMapper.selectByUserId(userId);
    }


    @Transactional
    public void del(Integer userId){
        UserRole urole = new UserRole();
        urole.setUserId(String.valueOf(userId));
        userRoleMapper.delete(urole);  // 首先删除用户拥有的角色
        userMapper.deleteByPrimaryKey(userId);

    }

    public int register(User user) {
        int a = userMapper.insert(user);
        return a;
    }

}
